﻿using MQTTnet;
using MQTTnet.Client;
using MQTTnet.Protocol;
using MQTTnet.Server;
using Newtonsoft.Json;
using System;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
//using System.Text.Json;
//using System.Text.Json.Serialization;
using System.Text.Unicode;
using System.Threading;
using System.Threading.Tasks;
using System.Xml.Linq;
using static System.Net.WebRequestMethods;
using MqttServerTest.Model;

namespace MqttServerTest
{
    public class MyClient
    {
        private IMqttClient _mqttClient = null;
        public bool up = false;
        public int _point = 1883;
        //public string _tcpServer = "82.156.22.226";
        public string _tcpServer = "192.168.10.210";
        //public string _userName = "Huawow_cloud";
        //public string _passWord = "huawow_mqtt13";
        public string _userName = "admin";
        public string _passWord = "huawow";

        private string _clientID = "";
        //private static readonly string _uuid = "4A950F17-C665273B-EDED4D3C-BCF7B6AC";
        private static string _uuid = "ABD0F2A4-81581437-0DCA61AF-8D5C88F6";

        string[] id = new string[] { "4DE8976A-7F2E7C29-AC1FE75F-DD12CE2F", "616CC2E6-2819AE83-365D7A9D-9C404D5D",
            "66B060CC-DF7AAB23-B1700E6B-DADAACB4","374A3551-3C304462-7CA295C2-C0531C49","950D5AE5-90138CCF-09AE748C-B3178302",
        "5905D1C5-77E2927C-5ECAB5E9-3F252693","8577BBB8-4ED59923-FB0C91E0-FA111DC4","FE55CFA2-8C3CCCBA-D92D4802-4568468C",
        "9C072B45-75F4B8DC-54BC07B1-A9A888FE","95810DD3-52C2C0A0-B7D02410-DE06189A","7945E47F-252C2385-FA35779E-F2E987C2",
            "15FA039A-DD4732CC-61ABCB9C-DB28470E","807EBD51-A3CB0212-4F184E49-79A45713","C5F32D77-223B10B0-5A40B4BE-18BB90D7",
        "4718499B-6D4B17FE-FC2E168E-1D0D3474"};

        MqttClientOptions options = null;

        JsonSerializerOptions op = new JsonSerializerOptions
        {
            PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
            Encoder = System.Text.Encodings.Web.JavaScriptEncoder.Create(UnicodeRanges.All),
            PropertyNameCaseInsensitive = true,
            DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault
        };
        //创建客户端
        MqttFactory mqttFactory = new MqttFactory();

        public async Task StartAsync()
        {
            //var caCert = X509Certificate.CreateFromCertFile(@"C:\HW\certs\server\ca.pem");
            //var caCert = X509Certificate.CreateFromCertFile(@"C:\ProgramData\HBHW\HWDataForwarding\Web\certs\server\ca.pem");
            //var caCert = new X509Certificate2(@"C:\ProgramData\HBHW\HWDataForwarding\Web\certs\server\ca.pem");
            //var clientCert = new X509Certificate2(@"C:\HW\certs\server\1\device.pfx", "huawowcloud");

            try
            {
                _clientID = "Cloud-" + Guid.NewGuid().ToString();
                Console.Title = "Client";

                //设置客户端参数
                options = new MqttClientOptionsBuilder()
                    .WithClientId(_clientID)    //客户端ID
                    .WithTcpServer(_tcpServer, _point)   //服务器地址
                    .WithCredentials(_userName, _passWord)   //用户名，密码
                    .WithProtocolVersion(MQTTnet.Formatter.MqttProtocolVersion.V500)    //MQTT版本
                                                                                        //.WithTls()
                    /*.WithTls(new MqttClientOptionsBuilderTlsParameters()
                    {
                        UseTls = true,
                        SslProtocol = System.Security.Authentication.SslProtocols.Tls12,
                        AllowUntrustedCertificates = true,//允许不受信任的证书
                        IgnoreCertificateChainErrors = true,//忽略证书链错误
                        IgnoreCertificateRevocationErrors = true,//忽略证书撤销错误
                        Certificates = new List<X509Certificate>()
                        {
                            caCert,
                            clientCert
                        },
                        //CertificateValidationHandler = _ => true
                        CertificateValidationHandler = eventArgs =>
                        {
                            eventArgs.Certificate.Subject.DumpToConsole();
                            eventArgs.Certificate.GetExpirationDateString().DumpToConsole();
                            eventArgs.Chain.ChainPolicy.RevocationMode.DumpToConsole();
                            eventArgs.Chain.ChainStatus.DumpToConsole();
                            eventArgs.SslPolicyErrors.DumpToConsole();
                            return true;
                        }
                    })*/
                    .WithWillDelayInterval(10)
                    .WithKeepAlivePeriod(TimeSpan.FromSeconds(30))
                    .WithCleanSession()
                    .WithCleanStart()
                    .WithWillTopic("/will/bye")
                    .WithWillPayload("离线")
                    .WithUserProperty("test", "huawow11")
                    .Build();




                _mqttClient = mqttFactory.CreateMqttClient();

                _mqttClient.ConnectedAsync += OnMqttClientConntecedAsync;

                _mqttClient.DisconnectedAsync += OnMqttClientDisconnectedAsync;

                _mqttClient.ApplicationMessageReceivedAsync += OnSubscriberMessageReceived;

                await _mqttClient.ConnectAsync(options, CancellationToken.None);
                Console.WriteLine("初始化完成！");


            }
            catch (Exception ex)
            {
                Console.WriteLine($"客户端连接出错.>{ex.Message}");

            }

            await LoopAsync();
        }

        private async Task LoopAsync()
        {
            try
            {
                Console.WriteLine("请选择运行模式");
                Console.WriteLine("0：退出程序");
                Console.WriteLine("1：获取硬件信息");
                Console.WriteLine("2：获取设备状态信息");
                Console.WriteLine("3：获得设备传感器边缘计算服务参数");
                Console.WriteLine("4：配置传感器设备主动采集服务参数");
                Console.WriteLine("5：传感器设备主动采集注册");
                Console.WriteLine("6：传感器设备主动采集注销");
                Console.WriteLine("7：写入连接传感器设备");

                Console.WriteLine("8：控制设备");
                Console.WriteLine("9：获得设备串口参数");
                Console.WriteLine("10：配置串口参数");
                Console.WriteLine("11：获取蜂窝网服务小区信息");

                Console.WriteLine("12：升级");

                Console.WriteLine("13：发送短信");
                Console.WriteLine("14：获取设备传感器列表");
                Console.WriteLine("15：获取设备寄存器列表");

                Console.WriteLine("16：下载业务程序");
                Console.WriteLine("17：删除业务程序");
                Console.WriteLine("18：获取透传配置");
                Console.WriteLine("19：配置透传");

                Console.WriteLine("20：获取WIFI配置");
                Console.WriteLine("21：配置设备WIFI");

                string topic = null;

                while (!string.IsNullOrEmpty(topic = Console.ReadLine()))
                {
                    switch (topic)
                    {
                        case "0":
                            StopAsync();
                            return;
                        case "1"://获取硬件信息
                                 //ClientPublishMqttTopicAsync("hello/world", "123").GetAwaiter().GetResult();
                            ClientPublishMqttTopicAsync("huawow/server/" + _uuid + "/thing/service/hwinfo/get", JsonConvert.SerializeObject(new Hwinfo())).GetAwaiter().GetResult();
                            //foreach (var i in id)
                            //{
                            //    ClientPublishMqttTopicAsync("huawow/server/" + i + "/thing/service/hwinfo/get", JsonConvert.SerializeObject(new hwinfo()));
                            //}
                            break;
                        case "2"://获取状态信息
                            _ = ClientPublishMqttTopicAsync("huawow/server/" + _uuid + "/thing/service/status/get", JsonConvert.SerializeObject(new Status()));
                            break;
                        case "3"://获得设备传感器边缘计算服务参数
                            await ClientPublishMqttTopicAsync("huawow/server/" + _uuid + "/thing/service/sensor/get", JsonConvert.SerializeObject(new Status()));
                            break;
                        case "4"://设置设备传感器边缘计算服务参数
                            {
                                Sensor sensor = new Sensor();
                                Console.WriteLine("是否启动？(y/n)");
                                var s = Console.ReadLine();
                                if (s == "y")
                                    sensor.Enabled = "true";
                                else
                                    sensor.Enabled = "false";
                                Console.WriteLine("选择串口？(1/2)");
                                var c = Console.ReadLine();
                                if (c == "1")
                                    sensor.Port = "com1";
                                else
                                    sensor.Port = "com2";

                                await ClientPublishMqttTopicAsync("huawow/server/" + _uuid + "/thing/service/sensor/set", JsonConvert.SerializeObject(sensor));
                                break;
                            }
                        case "5"://传感器设备主动采集注册
                            {
                                Registers register = new Registers();
                                Console.WriteLine("选择串口？(1/2)");
                                var c1 = Console.ReadLine();
                                if (c1 == "1")
                                    register.Port = "com1";
                                else
                                    register.Port = "com2";
                                await ClientPublishMqttTopicAsync("huawow/server/" + _uuid + "/thing/service/sensor/register", JsonConvert.SerializeObject(register));
                                break;
                            }
                        case "6"://传感器设备主动采集注销
                            {
                                Unregister unregister = new Unregister();
                                Console.WriteLine("选择串口？(1/2)");
                                var c2 = Console.ReadLine();
                                if (c2 == "1")
                                    unregister.Port = "com1";
                                else
                                    unregister.Port = "com2";
                                await ClientPublishMqttTopicAsync("huawow/server/" + _uuid + "/thing/service/sensor/unregister", JsonConvert.SerializeObject(unregister));
                                break;
                            }
                        case "7"://写入传感器
                            {
                                RegistersR registersR = new RegistersR();
                                var c3 = Console.ReadLine();
                                if (c3 == "1")
                                    registersR.Port = "com1";
                                else
                                    registersR.Port = "com2";
                                var w = Console.ReadLine();
                                registersR.RegisterList[0].Value = Convert.ToInt32(w);
                                await ClientPublishMqttTopicAsync("huawow/server/" + _uuid + "/thing/service/sensor/write", JsonConvert.SerializeObject(registersR));
                                break;
                            }
                        case "8"://控制设备
                            {
                                var act = new Model.Action();
                                Console.Write("是否重启(y/n)：");
                                string re = Console.ReadLine();
                                if (re == "y")
                                {
                                    act.Reboot = "true";
                                }
                                Console.Write("是否保存(y/n)：");
                                string sa = Console.ReadLine();
                                if (sa == "y")
                                {
                                    act.Save = "true";
                                }
                                Console.Write("是启动程序(y/n)：");
                                string pm = Console.ReadLine();
                                if (pm == "y")
                                {
                                    act.Reset_App = "true";
                                }
                                await ClientPublishMqttTopicAsync("huawow/server/" + _uuid + "/thing/service/device/action", JsonConvert.SerializeObject(act));
                                break;
                            }
                        case "9"://获得485串口配置
                            await ClientPublishMqttTopicAsync("huawow/server/" + _uuid + "/thing/service/serial_port/get", JsonConvert.SerializeObject(new Status()));
                            break;
                        case "10"://设置485串口
                            {
                                PeiRS peiRS = new PeiRS();
                                Console.WriteLine("是否启动？(y/n)");
                                var e = Console.ReadLine();
                                peiRS.Enabled = e == "y" ? "true" : "false";

                                Console.WriteLine("选择串口？(1/2)");
                                var e1 = Console.ReadLine();
                                peiRS.Port = e1 == "1" ? "com1" : "com2";

                                Console.WriteLine("选择模式:1tcp,2udp,3modbus");
                                var m = Console.ReadLine();
                                if (m == "1")
                                {
                                    peiRS.Mode = "tcp_client";
                                }
                                else if (m == "2")
                                {
                                    peiRS.Mode = "udp_client";
                                }
                                else
                                {
                                    peiRS.Mode = "modbus";
                                }

                                await ClientPublishMqttTopicAsync("huawow/server/" + _uuid + "/thing/service/serial_port/set", JsonConvert.SerializeObject(peiRS));
                                break;
                            }
                        case "11"://获取蜂窝网服务小区信息
                            await ClientPublishMqttTopicAsync("huawow/server/" + _uuid + "/thing/service/cell/get", JsonConvert.SerializeObject(new Status()));
                            break;
                        case "12"://升级
                            FTPUp fTPUp = new FTPUp
                            {
                                Sha256sum = ComputeFileSHA256.ComputeFiel("d:/hw1570g-a_6.2.3.bin")
                                //sha256sum = ComputeFileSHA256.ComputeFiel("d:/hw1570l-r.bin")
                            };
                            await ClientPublishMqttTopicAsync("huawow/server/" + _uuid + "/thing/service/firmware/set", JsonConvert.SerializeObject(fTPUp));
                            break;
                        case "13"://发送短信
                                  //for (int i = 0; i < 10; i++)
                                  //{
                            await ClientPublishMqttTopicAsync("huawow/server/" + _uuid + "/thing/service/sms/set", JsonConvert.SerializeObject(new Sms()));
                            Console.WriteLine(DateTime.Now);
                            Console.WriteLine(new Sms().Content.Length);
                            //Thread.Sleep(40 * 1000);
                            //}
                            break;
                        case "14"://获得传感器列表
                            await ClientPublishMqttTopicAsync("huawow/server/" + _uuid + "/thing/service/sensor/list", JsonConvert.SerializeObject(new Status()));
                            break;
                        case "15"://获得设备寄存器列表
                            var o = new { messageId = 825807, timestamp = Helper.GetTimeStamp(), Port = "com2", SensorName = "PH" };
                            await ClientPublishMqttTopicAsync("huawow/server/" + _uuid + "/thing/service/sensor/reglist", JsonConvert.SerializeObject(o));
                            break;
                        case "16"://下载业务程序
                            var app = new DownApp();
                            app.Url = "http://192.168.5.200:280/1.0.1.zip";
                            app.Sha256sum = ComputeFileSHA256.ComputeFiel("d:/1.0.1.zip");
                            app.IsRun = "true";
                            /*Console.WriteLine("选择下载类型？(1:程序/2:配置文件/3:License)");
                            var conf = Console.ReadLine();
                            if (conf == "1")
                            {
                                app.Url = "http://192.168.5.200:280/ProtocolHCPE";
                                app.Sha256sum = ComputeFileSHA256.ComputeFiel("d:/ProtocolHCPE(1)");
                                app.Type = "program";
                                app.IsRun = "true";
                            }
                            else if (conf == "2")
                            {
                                app.Url = "http://192.168.5.200:280/ProtocolHCPE.yaml";
                                app.Sha256sum = ComputeFileSHA256.ComputeFiel("d:/ProtocolHCPE.yaml");
                                app.Type = "config";
                            }
                            else if (conf == "3")
                            {
                                app.Url = "http://192.168.5.200:280/ProtocolS7WebLicense.license";
                                app.Sha256sum = ComputeFileSHA256.ComputeFiel("d:/ProtocolS7WebLicense.license");
                                app.Type = "license";
                            }*/
                            await ClientPublishMqttTopicAsync("huawow/server/" + _uuid + "/thing/service/app/set", JsonConvert.SerializeObject(app));
                            break;
                        case "17"://删除程序
                            await ClientPublishMqttTopicAsync("huawow/server/" + _uuid + "/thing/service/app/del", JsonConvert.SerializeObject(new Status()));
                            break;
                        case "18"://获取透传配置
                            await ClientPublishMqttTopicAsync("huawow/server/" + _uuid + "/thing/service/dtu/get", JsonConvert.SerializeObject(new Status()));
                            break;
                        case "19"://设置透传
                            var dtu = new DtuSet();
                            await ClientPublishMqttTopicAsync("huawow/server/" + _uuid + "/thing/service/dtu/set", JsonConvert.SerializeObject(dtu));
                            break;
                        case "20"://获取WIFI配置
                            await ClientPublishMqttTopicAsync("huawow/server/" + _uuid + "/thing/service/wifi/get", JsonConvert.SerializeObject(new Status()));
                            break;
                        case "21"://设置设备WIFI
                            {
                                Console.WriteLine("选择WIFI类型？(1:AP,2:STA,3:MESH)");
                                var mode = Console.ReadLine();
                                if (mode == "1")
                                {
                                    await ClientPublishMqttTopicAsync("huawow/server/" + _uuid + "/thing/service/wifi/set", JsonConvert.SerializeObject(new WIFI_AP()));
                                    break;
                                }
                                if (mode == "2")
                                {
                                    await ClientPublishMqttTopicAsync("huawow/server/" + _uuid + "/thing/service/wifi/set", JsonConvert.SerializeObject(new WIFI_STA()));
                                    break;
                                }
                                if (mode == "3")
                                {
                                    await ClientPublishMqttTopicAsync("huawow/server/" + _uuid + "/thing/service/wifi/set", JsonConvert.SerializeObject(new WIFI_MESH()));
                                    break;
                                }
                                break;
                            }
                        default:
                            break;
                    }
                    Console.WriteLine("请选择运行模式");
                    Console.WriteLine("0：退出程序");
                    Console.WriteLine("1：获取硬件信息");
                    Console.WriteLine("2：获取设备状态信息");
                    Console.WriteLine("3：获得设备传感器边缘计算服务参数");
                    Console.WriteLine("4：配置传感器设备主动采集服务参数");
                    Console.WriteLine("5：传感器设备主动采集注册");
                    Console.WriteLine("6：传感器设备主动采集注销");
                    Console.WriteLine("7：写入连接传感器设备");

                    Console.WriteLine("8：控制设备");
                    Console.WriteLine("9：获得设备串口参数");
                    Console.WriteLine("10：配置串口参数");
                    Console.WriteLine("11：获取蜂窝网服务小区信息");

                    Console.WriteLine("12：升级");

                    Console.WriteLine("13：发送短信");
                    Console.WriteLine("14：获取设备传感器列表");
                    Console.WriteLine("15：获取设备寄存器列表");

                    Console.WriteLine("16：下载业务程序");
                    Console.WriteLine("17：删除业务程序");
                    Console.WriteLine("18：获取透传配置");
                    Console.WriteLine("19：配置透传");

                    Console.WriteLine("20：获取WIFI配置");
                    Console.WriteLine("21：配置设备WIFI");

                }
            }
            catch (Exception ex)
            {

                Console.WriteLine(ex.Message);
            }
        }

        public async void StopAsync()
        {
            try
            {
                if (_mqttClient == null)
                {
                    return;
                }
                //方式一
                //未触发遗嘱消息
                await _mqttClient.DisconnectAsync(new MqttClientDisconnectOptionsBuilder().WithReason(MqttClientDisconnectOptionsReason.NormalDisconnection).Build());

                //方式二
                //未触发遗嘱消息
                //var mqttClientDisconnectOptions = mqttFactory.CreateClientDisconnectOptionsBuilder().Build();
                //await _mqttClient.DisconnectAsync(mqttClientDisconnectOptions, CancellationToken.None);

                //方式三
                //未触发遗嘱消息
                //await _mqttClient.DisconnectAsync(MqttClientDisconnectOptionsReason.ImplementationSpecificError);

                //方式四
                //未触发遗嘱消息
                //_mqttClient.Dispose();

                _mqttClient = null;
            }
            catch (Exception ex)
            {

                Console.WriteLine($"客户端连接出错{ex.Message}");
            }
        }

        //Retain的用法：Retain意为保留，设为True表示这条消息发布的时候如果没有订阅者，则该消息保留在Server端，直到被人订阅时立刻发布出去并删除，设为False时则没有这样的效果。
        //MQTT Client发布消息
        public async Task ClientPublishMqttTopicAsync(string topic, string paylod)
        {
            try
            {
                var message = new MqttApplicationMessageBuilder()
                    .WithTopic(topic)   //主题
                    .WithPayload(paylod)    //消息
                    .WithQualityOfServiceLevel(MqttQualityOfServiceLevel.AtLeastOnce)   //消息等级
                    .WithRetainFlag(false)  //是否保留消息
                                            //.WithUserProperty("hello", "property_test")  //用户属性
                    .Build();

                await _mqttClient.PublishAsync(message);
                Console.WriteLine(string.Format("客户端[{0}]发布主题[{1}]成功.", _mqttClient.Options.ClientId, topic));
                Console.WriteLine(string.Format("发布的消息内容为：{0}-{1}.", DateTime.Now, paylod));
            }
            catch (Exception ex)
            {

                Console.WriteLine(string.Format("客户端[{0}]发布主题[{1}]异常！>{2}", _mqttClient.Options.ClientId, topic, ex.Message));
            }
        }

        //MQTT Client订阅消息
        public async Task ClientSubscribeTopicAsync(string topic)
        {
            //var t = new MqttTopicFilterBuilder().WithAtLeastOnceQoS().WithNoLocal().WithRetainAsPublished().WithTopic(topic).Build();
            try
            {
                await _mqttClient.SubscribeAsync(topic, MqttQualityOfServiceLevel.AtLeastOnce);
                //await _mqttClient.SubscribeAsync(t);
                Console.WriteLine(string.Format("客户端[{0}]订阅主题[{1}]成功", _mqttClient.Options.ClientId, topic));
            }
            catch (Exception ex)
            {

                Console.WriteLine(string.Format("客户端[{0}]订阅主题[{1}]失败！", _mqttClient.Options.ClientId, topic) + " Exception=" + ex.Message);
            }
        }

        //MQTT Client取消订阅消息
        public async void ClientUnSubscribeTopicAsync(string topic)
        {
            await _mqttClient.UnsubscribeAsync(topic);
            Console.WriteLine(string.Format("客户端[{0}]取消订阅[{1}]主题", _mqttClient.Options.ClientId, topic));
        }

        //客户端连接
        public async Task OnMqttClientConntecedAsync(MqttClientConnectedEventArgs e)
        {
            Console.WriteLine("连接成功 + {0} : {1}", Environment.CurrentManagedThreadId, _clientID);

            //订阅设备上线
            //await ClientSubscribeTopicAsync("huawow/device/register/+");
            //await ClientSubscribeTopicAsync("huawow/device/#");
            //await ClientSubscribeTopicAsync("$SYS/#");
            //await ClientSubscribeTopicAsync("$foo/bar");
            await ClientSubscribeTopicAsync("#");
            //await ClientSubscribeTopicAsync($"huawow/device/{_uuid}/thing/service/alarm");


            //订阅心跳主题
            //await ClientSubscribeTopicAsync("huawow/device/+/thing/event/property/post");

            //订阅串口心跳
            //ClientSubscribeTopic("huawow/device/+/thing/event/sensor/post");

            //订阅硬件信息
            await ClientSubscribeTopicAsync("huawow/device/+/thing/service/hwinfo/get_reply");

            //订阅状态信息
            //await ClientSubscribeTopicAsync("huawow/device/+/thing/service/status/get_reply");

            //订阅告警信息
            //ClientSubscribeTopic("huawow/device/+/thing/event/alarm");

            //订阅主动采集服务参数回应
            //ClientSubscribeTopic("huawow/device/+/thing/service/sersor/set_reply");

            //订阅主动采集
            //await ClientSubscribeTopicAsync($"huawow/device/{_uuid}/thing/event/sub/sensor");

            //订阅写入传感器回应
            //await ClientSubscribeTopicAsync("huawow/device/+/thing/event/sensor/write_reply");

            //订阅设备传感器边缘计算服务参数
            //ClientSubscribeTopic("huawow/device/+/thing/service/sensor/get_reply");

            //订阅485 串口信息
            //ClientSubscribeTopic("huawow/device/+/thing/service/rs485/get_reply");
            //ClientSubscribeTopic("/gateway-to-user/data-send/#");
            //ClientSubscribeTopic("hello");

            //订阅蜂窝网服务小区信息
            //ClientSubscribeTopic("huawow/device/+/thing/service/cell/get_reply");
            //ClientSubscribeTopic("huawow/device/+/thing/event/sensor/list_reply");


        }

        //客户端断开连接
        public async Task OnMqttClientDisconnectedAsync(MqttClientDisconnectedEventArgs e)
        {
            //Console.WriteLine(e.);
            //Console.WriteLine("断开连接");
            string msg = string.Format("Time:{0}\t客户端[{1}]断开连接\t---ClientWasConnected:{2}\t---msg:{3}\t---Reason:{4}\r\n", DateTime.Now, _clientID, e.ClientWasConnected, e.Exception == null ? "" : e.Exception.Message, e.Reason);

            Console.WriteLine(msg);

            //自动重连
            await Task.Delay(TimeSpan.FromSeconds(10));
            try
            {
                await _mqttClient.ConnectAsync(options, CancellationToken.None);
                string m = string.Format("Time:{0},重连成功\r\n", DateTime.Now);
            }
            catch (Exception ex)
            {

                string m = string.Format("Time:{0},重连失败，{1}\r\n", DateTime.Now, ex.Message);
                Console.WriteLine(m);

            }
        }

        /// <summary>
        /// 当客户端连接收到所订阅的主题消息时
        /// </summary>
        /// <param name="e"></param>
        private Task OnSubscriberMessageReceived(MqttApplicationMessageReceivedEventArgs e)
        {
            Task.Run(() =>
            {
                string text = Encoding.UTF8.GetString(e.ApplicationMessage.PayloadSegment);
                //Console.WriteLine(text.Length);
                string topic = e.ApplicationMessage.Topic;
                string Qos = e.ApplicationMessage.QualityOfServiceLevel.ToString();
                string Retained = e.ApplicationMessage.Retain.ToString();

                var tp = topic.Split('/');
                Console.Write($"{DateTime.Now} : ");
                Console.Write($"{e.ClientId} : ");
                Console.WriteLine("MessageReceived >> Topic:{0},Qos:{1},Retained:{2}", topic, Qos, Retained);
                Console.WriteLine("MessageReceived >> MSG:{0}", text);
                //Console.WriteLine(text.IndexOf("value"));

                if (topic.StartsWith('/'))
                {
                    TImeTEst t = JsonConvert.DeserializeObject<TImeTEst>(text);
                    Console.WriteLine("这是时间戳；{0}", t.sendTime);
                    var time = Helper.TimeStampToDateTime(t.sendTime).ToLocalTime();
                    Console.WriteLine("这是转换后的时间：{0}", time.ToString("yyyy/MM/dd HH:mm:ss.fff"));
                }

                if (tp.Length > 2 && tp[2] == "register")
                {
                    Device a = JsonConvert.DeserializeObject<Device>(text);
                    //_uuid = a.UUID;
                    Console.WriteLine(_uuid);

                }

                if (tp[^1] == "sensor")
                {
                    SensorData data = JsonConvert.DeserializeObject<SensorData>(text);

                    //var b = Encoding.UTF8.GetBytes(data.Value);

                    Console.WriteLine(data.Data);

                    Console.WriteLine("----------------------");
                }

                Console.WriteLine();
                //return Task.CompletedTask;
            }, CancellationToken.None);

            return Task.CompletedTask;
        }

    }

    public static class Helper
    {
        /// <summary>
        /// 获取当前时间戳
        /// </summary>
        /// <returns></returns>
        public static long GetTimeStamp()
        {

            //string time_stamp = DateTimeOffset.Now.ToUnixTimeSeconds().ToString();//秒级
            //string time_stamp = DateTimeOffset.Now.ToUnixTimeMilliseconds().ToString();//毫秒级

            TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
            //毫秒级
            var timestamp = Convert.ToInt64(ts.TotalMilliseconds);
            //秒级
            //var timestamp = Convert.ToInt64(ts.TotalSeconds);
            //return timestamp;
            return DateTimeOffset.Now.ToUnixTimeMilliseconds();
        }

        /// <summary>
        /// 将时间戳转换为时间
        /// </summary>
        /// <param name="timeStamp"></param>
        /// <returns></returns>
        public static DateTime TimeStampToDateTime(long timeStamp)
        {
            /*DateTime startTime = new DateTime(1970, 1, 1);//当地时区  
            var time = startTime.AddMilliseconds(timeStamp);
            return time;*/
            return DateTimeOffset.FromUnixTimeMilliseconds(timeStamp).LocalDateTime;
        }

        /// <summary>
        /// 数字科学计数法处理
        /// </summary>
        /// <param name="strData"></param>
        /// <returns></returns>
        private static decimal ChangeToDecimal(string strData)
        {
            Decimal dData = 0.0M;
            if (strData.Contains("E"))
            {
                dData = Convert.ToDecimal(Decimal.Parse(strData.ToString(), System.Globalization.NumberStyles.Float));
            }
            else
            {
                dData = Convert.ToDecimal(strData);
            }
            return Math.Round(dData, 4);
        }
    }
}
